import { Component, ViewChild, Input, Output, EventEmitter, ChangeDetectorRef } from '@angular/core';
import { PortfolioService } from '../portfolio.service';
import { LrtmService, LongRunningTaskTypeEnum } from '../../../framework/lrtm/lrtm.service';
import { StorageService } from '../../../shared/services/storage.service';
import { Observable } from 'rxjs/Observable';
import { AppComponent } from '../../../app.component';
import { PortfolioFilterModel } from '../models/portfolioFilter.model';
import { PortfolioBaseModel, PortfolioModel } from '../models/portfolio.model';
import { ColumnOptions } from '../../../shared/components/table/models/columnOptions.model';
import { PaginationPositionDisplayEnum, TableComponent } from '../../../shared/components/table/table.component';
import { TableRouterLink } from '../../../shared/components/table/models/tableRouterLink.model';
import { TableOptions } from '../../../shared/components/table/models/tableOptions.model';
import { TableButton } from '../../../shared/components/table/models/tableButton.model';
import { PortfolioAction } from '../models/portfolioAction.model';
import { PortfolioSharingStatus } from '../models/portfolioSharingStatus.model';
import { PortfolioType } from '../models/portfolioType.model';
import swal, { SweetAlertOptions } from 'sweetalert2';
import { UtilsService } from '../../../shared/services/utils.service';
import { AnalyticsService } from '../../../shared/services/googleAnalytics.service';
import { GoogleAnalyticsBeacon } from '../../../shared/models/googleAnalytics.model';
import { BaseComponent } from '../../../shared/components/baseComponent/base.component';
import { PortfolioMonitoringStatusModel } from '../models/portfolioMonitoringStatus.model';

@Component({
    selector: 'list-portfolio',
    templateUrl: './portfolioList.component.html',
    styleUrls: ['./portfolioList.component.scss', '../../../../assets/table.scss'],
    providers: [PortfolioService]
})
export class PortfolioListComponent extends BaseComponent {
    public filter: PortfolioFilterModel = new PortfolioFilterModel();
    public portfolioColumns: ColumnOptions[];

    public setColumns() {

        this.hasMonitoringClaim = this.hasPermission('api/v1/subscribetoportfolio',  'PUT', [{  key:  'alert',  value:  'quarterly'  }]);

        if (this.hasMonitoringClaim) {
            this.portfolioColumns = [
                new ColumnOptions('NameLowercase', 'PortfolioName', 'Portfolio Name', 'col-md-3', false, undefined, false, null, false, true, false, true),
                new ColumnOptions('CompanyCount', 'Holdings', 'Holdings', 'col-md-1', false, undefined, false, null, true, false, false, true, undefined, false, false, true),
                new ColumnOptions('Sharing', 'Sharing', 'Sharing', 'col-md-1', false, undefined, false, null, true, false, true, true),
                new ColumnOptions('Monitoring', 'Monitoring', 'Monitoring', 'col-md-1', false, undefined, false, null, true, false, true, true),
                new ColumnOptions('CreatedBy', 'CreatedBy', 'CreatedBy', 'col-md-2', false, undefined, false, null, true, false, false, true, undefined, false, false, true),
                new ColumnOptions('LastEdited', 'LastEdited', 'Last Edited', 'col-md-2', false, undefined, false, null, true, false, false, true),
                new ColumnOptions('Actions', 'Actions', '', 'col-md-2', false, undefined, false, null, true, false, true, true)
            ];
        }
        else {
            this.portfolioColumns = [
                new ColumnOptions('NameLowercase', 'PortfolioName', 'Portfolio Name', 'col-md-3', false, undefined, false, null, false, true, false, true),
                new ColumnOptions('CompanyCount', 'Holdings', 'Holdings', 'col-md-1', false, undefined, false, null, true, false, false, true, undefined, false, false, true),
                new ColumnOptions('Sharing', 'Sharing', 'Sharing', 'col-md-1', false, undefined, false, null, true, false, true, true),
                new ColumnOptions('CreatedBy', 'CreatedBy', 'CreatedBy', 'col-md-2', false, undefined, false, null, true, false, false, true, undefined, false, false, true),
                new ColumnOptions('LastEdited', 'LastEdited', 'Last Edited', 'col-md-2', false, undefined, false, null, true, false, false, true),
                new ColumnOptions('Actions', 'Actions', '', 'col-md-2', false, undefined, false, null, true, false, true, true)
            ];
        }

    }

    public portfolioSource: any[] = [];
    public paginationPosition = PaginationPositionDisplayEnum.Down;
    public portfolioList: PortfolioModel[];
    public portfolioCount: number;
    public routePath: string = '/portfolios/edit/';
    private userId: string;
    private accountId: string;
    private tableOptions: TableOptions;

    //Portfolio Monitoring
    public portfolioAlertsIds: any[];
    public portfolioMonitoringId: string;
    public hasMonitoringClaim: boolean;

    @ViewChild('table') table: TableComponent;

    @Input() portfolioStatus: PortfolioSharingStatus;
    @Input() myPortfolios = false;
    @Input() portfolioType: PortfolioType;
    @Input() isMonitorAllChecked: boolean;
    @Input() monitoringStatus: PortfolioMonitoringStatusModel;

    @Output() reloadPortfolios: EventEmitter<any> = new EventEmitter();

    constructor(
        private rootComponent: AppComponent,
        private portfolioService: PortfolioService,
        private lrtmService: LrtmService,
        private cdRef: ChangeDetectorRef,
        private analyticsService: AnalyticsService) {
        super(cdRef);
    }

    ngOnInit() {
        this.setColumns();
        let userInfo = StorageService.get().userInfo;
        this.userId = userInfo.userId;
        this.accountId = userInfo.accountId;

        this.portfolioSource = [];
        this.tableOptions = new TableOptions("NameLowercase");
        this.getBulkPortfolios();
    }

    public getBulkPortfolios() {
        var obsGet: Observable<PortfolioModel[]> = this.portfolioService.getPortfolio(this.tableOptions.pageOptions.skip, this.tableOptions.pageOptions.take, this.tableOptions.orderByCol, this.tableOptions.orderByAsc, this.portfolioStatus, this.portfolioType);
        var obsArray: Observable<any>[] = [obsGet];
        if (this.tableOptions.pageOptions.listOnly == false) {
            this.filter.sharingStatus = this.portfolioStatus;
            let obsCount: Observable<number> = this.portfolioService.getPortfolioCount(this.filter, this.portfolioType);
            obsArray.push(obsCount);
        }

        Observable.forkJoin(obsArray).subscribe((data) => {
            this.portfolioList = data[0] as PortfolioModel[];

            if (this.tableOptions.pageOptions.listOnly == false) {
                this.portfolioCount = (data[1] as number);
                //if (this.pagination) this.pagination.goTo(1, false);
                this.rootComponent.finishLoading();
            }

            let valuesToDisplay: any[];

            if(this.hasMonitoringClaim)
            {
                valuesToDisplay = this.portfolioList.map(portfolio => {
                    return {
                        namePortfolio: new TableRouterLink(portfolio.name, true, this.routePath + portfolio.id, null, true),
                        companyCount: portfolio.companyCount,
                        sharing: portfolio.isSystemPortfolio ? '' : this.getUpdatePortfolioStatusButton(portfolio),
                        monitoring: this.getUpdatePortfolioMonitoringButton(portfolio),
                        createdBy: portfolio.addedByFullName,
                        lastEdited: new Date(portfolio.dateModified),
                        actions: this.getActionButtonsForPortfolio(portfolio)
                    };
                });
            }
            else {
                valuesToDisplay = this.portfolioList.map(portfolio => {
                    return {
                        namePortfolio: new TableRouterLink(portfolio.name, true, this.routePath + portfolio.id, null, true),
                        companyCount: portfolio.companyCount,
                        sharing: portfolio.isSystemPortfolio ? '' : this.getUpdatePortfolioStatusButton(portfolio),
                        createdBy: portfolio.addedByFullName,
                        lastEdited: new Date(portfolio.dateModified),
                        actions: this.getActionButtonsForPortfolio(portfolio)
                    };
                });
            }
            
            this.portfolioSource = valuesToDisplay;
        });
    }

    private changePortfolioSharingStatus(info: any) {
        const swalOptions: SweetAlertOptions = Object.assign(UtilsService.getBaseSwalOptions(), {
            title: 'Portfolio Sharing',
            text: 'Are you sure you want to ' + (info.isChecked ? 'unshare' : 'share') + ' this portfolio?',
            confirmButtonText: (info.isChecked ? 'Unshare' : 'Share'),
            imageUrl: '/assets/icons-svg/icon-portfolio-sharing.svg'
        });
        swal(swalOptions).then(result => {
            if (result && result.value) {
                const status = (info.portfolio.sharingStatus === PortfolioSharingStatus.Shared)
                    ? PortfolioSharingStatus.Private
                    : PortfolioSharingStatus.Shared;
                this.portfolioService.updatePortfolioStatus(info.portfolio.id, status.toString())
                    .subscribe(() => {
                        this.reloadPortfolios.emit();
                        this.rootComponent.showSuccess("Portfolio status successfully updated.", "Success");
                    });
            } else {
                info.isChecked = !info.isChecked;
            }
        });
    }

    private changePortfolioMonitoredStatus(portfolioInfo: any) {
        const swalOptions: SweetAlertOptions = Object.assign(UtilsService.getBaseSwalOptions(), {
            title: 'Portfolio Monitoring',
            text: (portfolioInfo.isChecked ? 'Remove' : 'Add') + ' this portfolio ' + (portfolioInfo.isChecked ? 'from' : 'to') + ' your alerts?',
            confirmButtonText: 'Confirm',
            imageUrl: '/assets/icons-svg/icon-alerts-warning.svg'
        });
        swal(swalOptions).then(result => {
            if (result && result.value) {
                this.portfolioService.modifyPortfolioSubscription(portfolioInfo, this.monitoringStatus, this.userId, this.accountId).subscribe(
                    response => {
                        if(response != null) this.rootComponent.showSuccess(response.message, "Success!"); 
                        this.reloadPortfolios.emit();
                    }
                )
            } 
            else {
                portfolioInfo.isChecked = !portfolioInfo.isChecked;
            }
        });
    }

    private getUpdatePortfolioStatusButton(portfolio: PortfolioModel): TableButton[] {
        let isShared: boolean = portfolio.sharingStatus == PortfolioSharingStatus.Shared || portfolio.sharingStatus == PortfolioSharingStatus.All;
        let buttonText: string = isShared ? "Yes" : "No";

        return [new TableButton(buttonText, {
            action: PortfolioAction.UpdateSharingStatus,
            info: {
                portfolio: portfolio,
                isChecked: isShared
            }
        },
            portfolio.isMyPortfolio,
            2
        )];
    }

    private getUpdatePortfolioMonitoringButton(portfolio: PortfolioModel): TableButton[] {
        //this could be simplified, if portfolioMoniteredIdsList is null no other checks should be made
        let isMonitored: boolean = this.monitoringStatus.portfoliosMonitoredIds != null ? this.monitoringStatus.portfoliosMonitoredIds.some(portfolioId => portfolioId == portfolio.id) : false;
        let buttonText: string = isMonitored ? "Yes" : "No";

        let monitorChecked = isMonitored || this.monitoringStatus.isMonitoringAll;

        return [new TableButton(buttonText, {
            action: PortfolioAction.UpdateMonitoringStatus,
            info: {
                portfolio: portfolio,
                isChecked: monitorChecked
            }
        },
            !this.monitoringStatus.isMonitoringAll,
            2
        )];
    }

    private getActionButtonsForPortfolio(portfolio: PortfolioModel): TableButton[] {
        let buttons: TableButton[] = [];
        if (portfolio.isSystemPortfolio === false) {
            buttons.push(new TableButton("Export", {
                action: PortfolioAction.Export,
                portfolio: portfolio
            }));
        }
        return buttons;
    }

    private addTaskExportPortfolio(portfolio: PortfolioBaseModel) {
        let userInfo = StorageService.get().userInfo;
        var data = {
            id: portfolio.id,
            accountId: userInfo.accountId,
            userId: userInfo.userId,
            name: portfolio.name
        };
        this.analyticsService.sendBeacon(new GoogleAnalyticsBeacon('ExcelPortfolioExport', 'Portfolio Management', { PortfolioId: portfolio.id }));
        var date = UtilsService.getReportDate();
        this.lrtmService.runTask(this.rootComponent, 'Portfolio_' + portfolio.name + '_' + date, LongRunningTaskTypeEnum.PortfolioExportExcel, data, true, null).subscribe(data => {
        });
    }

    public onButtonClicked(actionOptions: any): void {
        switch (actionOptions.action) {
            case PortfolioAction.Export:
                this.addTaskExportPortfolio(actionOptions.portfolio);
                break;
            case PortfolioAction.UpdateSharingStatus:
                this.changePortfolioSharingStatus(actionOptions.info);
                break;
            case PortfolioAction.UpdateMonitoringStatus:
                this.changePortfolioMonitoredStatus(actionOptions.info);
                break;
        }
    }

    public tableOptionsChanged(tableOptions: TableOptions): void {
        this.tableOptions = tableOptions;
        this.getBulkPortfolios();
    }


}